﻿using MongoDB.Driver;
using System.Linq.Expressions;
using Testudo.Core;

namespace Testudo.Mongo;

internal class TenantMongoRepository<TEntity>
    : MongoRepository<TEntity>, ITenantRepository<TEntity>
    where TEntity : Entity, IEntity, ITenant
{
    public TenantMongoRepository(IMongoDatabase mongoDb)
        : base(mongoDb)
    {
    }

    public Guid TenantId { get; set; }
    public bool WithTenantId { get; init; }

    public override Task<TEntity> CreateAsync(TEntity target)
    {
        EnsureTenantId();
        target.TenantId = TenantId;
        return base.CreateAsync(target);
    }

    public override TEntity Create(TEntity entity)
    {
        EnsureTenantId();
        entity.TenantId = TenantId;
        return base.Create(entity);
    }

    protected override string GetCollectionName()
    {
        return WithTenantId ? $"{TenantId}_{typeof(TEntity).Name}" : base.GetCollectionName();
    }

    protected override Expression<Func<TEntity, bool>> EnsureFilter(Expression<Func<TEntity, bool>> filter,
        Expression<Func<TEntity, bool>> defaultFilter = null)
    {
        EnsureTenantId();
        var newFilter = filter != null ? filter.And(a => a.TenantId == TenantId) : a => a.TenantId == TenantId;
        return base.EnsureFilter(newFilter, defaultFilter);
    }

    private void EnsureTenantId()
    {
        if (TenantId == Guid.Empty) throw new Exception("TenantId not set");
    }
}